﻿/***************************************************************************
//* Foxit Software Inc.
//* Copyright(C) 2005-2012, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
/* and trade secrets of Foxit Software Inc.      
**************************************************************************
*/

/**
* PDF文档显示
*/

define(function (require, exports, module) {
    require('../PDFData/PDFDocument');
    var CPDF_PageView = require('./PDFPageView');
    require('./LayoutInfo');
    var CSinglePageViewLayout = require('./SinglePageViewLayout');
    var Config = require("../Config");
    var CPDF_Rect = require("../Math/Rect.js");
    var CPageInterval = function (nStartIndex, nEndIndex) {
        this.m_nStartIndex = nStartIndex;
        this.m_nEndIndex = nEndIndex;
    };
    FXREADER.PDFView.CPageInterval = CPageInterval;
    /**
     * Doc view
     * @class Doc view.
     * @constructor
     * @param {FXREADER.Data.CPDF_Document} pPDFDoc 	 PDF document object.
     * @param {FXREADER.PDFView.CImgPageViewRender} pPageViewRender render object.
 	* @param {String} MainFrameID  ID of the mainframe div.
 	* @param {FXREADER.PDFView.LayoutInfo} layoutInfo 	 layout infomation.
 	* @param {FXREADER.CReaderApp} pReaderApp 	 App object.
     * @return a doc view.
     */
    FXREADER.PDFView.CPDF_DocView = function (pPDFDoc, pPageViewRender, MainFrameID, layoutInfo, pReaderApp) {
        if (pPDFDoc == null)
            throw new Error("pPDFDoc is null!");
        var _PageViewList = {},               //页面列表;     
             _DocViewContainerID = MainFrameID + "_ViewContainer",
        //for the view mode of twopage;
             _LeftDocContainerID = MainFrameID + "_ViewContainer_1",
             _RightDocContainerID = MainFrameID + "_ViewContainer_2",
             _MainFrameID = MainFrameID,
             _pPDFDoc = pPDFDoc,
             _pViewLayout = null,
             _stLayoutInfo = layoutInfo,
             _pPageViewRender = pPageViewRender,
             _pReaderApp = pReaderApp,
        //滚动条api；
             _ScrollApi = null,
        //视口宽度；
             _DocViewWidth = 0,
        //视口高度；
             _DocViewHeight = 0,
        //视口左侧偏移；
             _DocViewOffsetLeft = 0,
        //视口顶侧偏移；
             _DocViewOffsetTop = 0,
        //当前页面索引;
             _iCurPageIndex = 0,
        //用于步进式页面创建，存储已经创建的页面列表，数组中每个对象为CPageInterval类型;
             _CreatedPageArray = [],
        //最宽页面;
             _nMaxPDFPageWidth = -1,
        //最高页面;
             _nMaxPDFPageHeight = -1,
             _Language = _pReaderApp.GetLanguage(),
             _bFitWidth = false,
             _pageIndexTooltipId = "fx_mobile_pageindex_tooltip",
             _tooltipTimeout = null,
             _self = this;
        
        var _documentScrollTimeout = null;
        _Construct();
        //private methods
        //构造函数;
        function _Construct() {
        	if(Config.defaultZoom == "FitWidth")
        	{
        		_bFitWidth = true;
        	}
        	else if(Config.defaultZoom != null)
        		_stLayoutInfo.dbScale = Config.defaultZoom;	
        }


        // 检查对应的页面是否已经创建;
        function _CheckPageCreated(nPageIndex) {
            for (var i = 0; i < _CreatedPageArray.length; i++) {
                var interval = _CreatedPageArray[i];
                if (interval.m_nStartIndex <= nPageIndex && interval.m_nEndIndex >= nPageIndex)
                    return true;
            }
            return false;
        }

        //根据页面索引，获取当前已经创建的，并且在对应页面之前，同时最接近对应页面的页面索引;
        function _GetInsertAfterIndex(nPageIndex) {
            var nInsertIndex = -1;
            var nMinDistance = nPageIndex;
            for (var i = 0; i < _CreatedPageArray.length; i++) {
                var interval = _CreatedPageArray[i];
                var tmpDistance = nPageIndex - interval.m_nEndIndex;
                if (tmpDistance > 0 && tmpDistance < nMinDistance) {
                    nMinDistance = tmpDistance;
                    nInsertIndex = interval.m_nEndIndex;
                }
            }
            return nInsertIndex;
        }


        //根据页面索引，获取需要创建的页面区间;
        function _GetPageInterval2Create(nPageIndex) {
            var maxPage2Create = Config.maxNewPagesPerTime;
            //为-1 表示创建所有页面;
            if (maxPage2Create == -1)
                maxPage2Create = _self.GetPageCount();
            var iStartIndex = parseInt(nPageIndex / maxPage2Create) * maxPage2Create;
            return new CPageInterval(iStartIndex, iStartIndex + maxPage2Create - 1);
        }

        //更新页面索引;
        function _UpdatePageIndex(oldPageIndex) {
            //      !_bThumb && _eViewerManager.UpdatePageIndex(_iCurPageIndex + 1);
            var pPageView = _self.GetPageView(_iCurPageIndex);
            //临时解决某些时候，快速拉动滚动条，会出现最后一页没有更新宽高的问题;
            if (!pPageView.IsScaleUpdated()) {
                pPageView.UpdateDimension(), pPageView.SetScaleUpdated(true);
            }
            //test
            var pCommandNextPage = _pReaderApp.GetCommand('GoNextPage');
            var pCommandPrevPage = _pReaderApp.GetCommand('GoPrevPage');
            var pCommandFirstPage = _pReaderApp.GetCommand('GoFirstPage');
            var pCommandLastPage = _pReaderApp.GetCommand('GoLastPage');
            if (_iCurPageIndex == 0) {
                pCommandFirstPage && pCommandFirstPage.SetState(false);
                pCommandPrevPage && pCommandPrevPage.SetState(false);
            }
            else {
                pCommandFirstPage && pCommandFirstPage.SetState(true);
                pCommandPrevPage && pCommandPrevPage.SetState(true);
            }

            if (_iCurPageIndex == _self.GetPageCount() - 1) {
                pCommandNextPage && pCommandNextPage.SetState(false);
                pCommandLastPage && pCommandLastPage.SetState(false);
            }
            else {
                pCommandNextPage && pCommandNextPage.SetState(true);
                pCommandLastPage && pCommandLastPage.SetState(true);
            }
            //end test

            var pUpdatePageCommand = _pReaderApp.GetCommand('UpdatePage');
            pUpdatePageCommand && pUpdatePageCommand.SetState(_iCurPageIndex + 1);
            if (oldPageIndex != _iCurPageIndex)
            {
            	if (FXREADER.Environment.mobile || FXREADER.Environment.iOS)
            	{
            		if(_tooltipTimeout)
            		{
            			clearTimeout(_tooltipTimeout);
            			_tooltipTimeout = null;
            			$('#'+_pageIndexTooltipId).trigger('hidetooltip');
            		}
                 	$('#'+_pageIndexTooltipId).tinytooltip({
            			message: function() {
            				return _iCurPageIndex+1 + " / " + _pPDFDoc.GetPageCount();;
            			},
            			hover: false,
            			floatRight: true
            		});
                 	$('#'+_pageIndexTooltipId).trigger('showtooltip');
            	}
            	_tooltipTimeout = setTimeout(function(){$('#'+_pageIndexTooltipId).trigger('hidetooltip');},2000);
            	_pReaderApp.OnDocPageIndexUpdated(oldPageIndex, _iCurPageIndex);
            }
            	
        };

        //public methods
        /**
         * @description Get the ID of doc view div.
         * @return {String} ID of doc view div.
         */
        this.GetDocViewContainerID = function () {
            return _DocViewContainerID;
        };
        /**
         * @description Get current page index.
         * @return {Number} current page index.
         */
        this.GetCurPageIndex = function () {
            return _iCurPageIndex;
        };
        /**
         * @description check whether the current zoom level is "FitWidth".
         * @return {Boolean} return true if the current zoom level is "FitWidth", otherwise, return false.
         */
        this.IsFitWidth = function()
        {
        	return _bFitWidth;
        };
        
        this.SetFitWidth = function(bFitWidth)
        {
        	_bFitWidth = bFitWidth;
        };


        this.GetLeftDocContainerID = function () {
            return _LeftDocContainerID;
        };
        this.GetRightDocContainerID = function () {
            return _RightDocContainerID;
        };

        //根据页面索引，生成对应页面的Container ID
        this.GetPageViewContainerID = function (nPageIndex) {
            return _DocViewContainerID + "_PageContainer_" + nPageIndex.toString();
        };
        //根据页面索引，生成对应页面背景图ID
        this.GetPageBGImgID = function (nPageIndex) {
            return _DocViewContainerID + "_BG_" + nPageIndex.toString();
        };
        //根据页面索引，生成对应页面Wrap ID
        this.GetWrapPageID = function (nPageIndex) {
            return _DocViewContainerID + "_Wrap_" + nPageIndex.toString();
        };
        //根据页面索引，生成对应页面Loading 图标 ID;
        this.GetPageLoaderImgID = function (nPageIndex) {
            return _DocViewContainerID + "_Loader_" + nPageIndex.toString();
        };
        /**
         * @description Get the PDF document object.
         * @return {FXREADER.Data.CPDF_Document} the PDF document object.
         */
        this.GetPDFDoc = function () {
            return _pPDFDoc;
        };
        /**
         * @description Get the page count of the PDF document.
         * @return {Number} The page count of the PDF document.
         */
        this.GetPageCount = function () {
            return _pPDFDoc.GetPageCount();
        };
        /**
         * @description Get the page view by page index.
 		* @param {Number} nPageIndex the page index
         * @return {FXREADER.PDFView.CPDF_PageView} page index.
         */
        this.GetPageView = function (nPageIndex) {
            return _PageViewList[nPageIndex];
        };

        //获取页面显示处理器
        this.GetPageViewRender = function () {
            return _pPageViewRender;
        };

        this.SetDocViewWidth = function (width) {
            _DocViewWidth = width;
        };
        /**
         * @description Get the width of the doc view.
         * @return {Number} The width of the doc view.
         */
        this.GetDocViewWidth = function () {
            return _DocViewWidth;
        };
        this.SetDocViewHeight = function (height) {
            _DocViewHeight = height;
        };
    	/**
         * @description Get the height of the doc view.
         * @return {Number} The height of the doc view.
         */
        this.GetDocViewHeight = function () {
            return _DocViewHeight;
        };

        this.SetDocViewOffsetLeft = function (nDocViewOffsetLeft) {
            _DocViewOffsetLeft = nDocViewOffsetLeft;
        };
        this.GetDocViewOffsetLeft = function () {
            return _DocViewOffsetLeft;
        };
        this.SetDocViewOffsetTop = function (nDocViewOffsetTop) {
            _DocViewOffsetTop = nDocViewOffsetTop;
        };
        this.GetDocViewOffsetTop = function () {
            return _DocViewOffsetTop;
        };
        /**
         * @description Get the rectangle of the doc view.
         * @return {FXREADER.CPDF_Rect} The rectangle of the doc view.
         */
        this.GetDocViewClientRect = function () {
            var docOffsetHtmlDoc = $("#" + this.GetDocViewContainerID()).offset();
            var docViewWidth = this.GetDocViewWidth();
            var docViewHeight = this.GetDocViewHeight();
            var docViewRect = new CPDF_Rect(docOffsetHtmlDoc.left, docOffsetHtmlDoc.top,
                             docOffsetHtmlDoc.left + docViewWidth, docOffsetHtmlDoc.top + docViewHeight);
            FXREADER.RectUtils.Normalize(docViewRect);
            return docViewRect;
        };

        this.GetMaxPDFPageWidth = function () {
            if (_nMaxPDFPageWidth != -1)
                return _nMaxPDFPageWidth;
            var pPDFDoc = _self.GetPDFDoc();
            var iPageCnt = pPDFDoc.GetPageCount();
            for (var i = 0; i < iPageCnt; i++) {
                var pPDFPage = pPDFDoc.GetPage(i);
                if (pPDFPage.GetPageWidth() > _nMaxPDFPageWidth)
                    _nMaxPDFPageWidth = pPDFPage.GetPageWidth();
            }
            return _nMaxPDFPageWidth;
        };

        this.GetMaxPDFPageHeight = function () {
            if (_nMaxPDFPageHeight != -1)
                return _nMaxPDFPageHeight;
            var pPDFDoc = _self.GetPDFDoc();
            var iPageCnt = pPDFDoc.GetPageCount();
            for (var i = 0; i < iPageCnt; i++) {
                var pPDFPage = pPDFDoc.GetPage(i);
                if (pPDFPage.GetPageHeight() > _nMaxPDFPageHeight)
                    _nMaxPDFPageHeight = pPDFPage.GetPageHeight();
            }
            return _nMaxPDFPageHeight;
        };

        this.GetMaxPageViewWidth = function () {
            return _self.GetMaxPDFPageWidth() * _pPageViewRender.GetPixelsPerPoint() * _self.GetScale();
        };

        this.GetMaxPageViewWidthNoScale = function () {
            return _self.GetMaxPDFPageWidth() * _pPageViewRender.GetPixelsPerPoint();
        };
        
        this.GetMaxPageViewHeight = function () {
            return _self.GetMaxPDFPageHeight() * _pPageViewRender.GetPixelsPerPoint() * _self.GetScale();
        };
        
        //初始化DocView;
        this.Init = function () {
            var iPageCnt = _pPDFDoc.GetPageCount();
            switch (_stLayoutInfo.nShowMode) {
                case FXREADER.PDFView.RD_BRMODE_CONTINUOUS:
                    _pViewLayout = new CSinglePageViewLayout(_self, _stLayoutInfo);
                    break;
                default:
                    break;
            }
            for (var i = 0; i < iPageCnt; i++) {
                _PageViewList[i] = new CPDF_PageView(_pPDFDoc.GetPage(i), _self, _DocViewContainerID);
            }
            var docViewHtml = _pViewLayout.CreateDocViewHtml();

            var jqMainFrameObj = $("#" + _MainFrameID);
            jqMainFrameObj.append(docViewHtml);
            if (FXREADER.Environment.mobile || FXREADER.Environment.iOS) {
            	var toolTipDivHtml = "<div id='"+_pageIndexTooltipId+"' style='display:none'></div>";
            	jqMainFrameObj.append(toolTipDivHtml);	
            }
            
            if (_stLayoutInfo.nShowMode == FXREADER.PDFView.RD_BRMODE_CONTINUOUS_FACING)
                _self.UpdateTwoPageContainerWidth();

            _self.CreatePages(0);
            _self.CreateCmdAndCmdUI();
            _pViewLayout.InitalizeScrollbar();
            _self.BindScrollEvent();
            _self.OnPageScroll();
        };
        /**
         * @description Set current zoom level to "FitWidth".
         */
        this.FitWidth = function()
        {
        	if(_self.IsFitWidth())
    			return;
    		var scale = _pViewLayout.GetFitWidthScale(true);
    		_self.SetFitWidth(true);
            _self.OnZoom(scale);
        };
        
        //public methods
        this.UpdateTwoPageContainerWidth = function () {
            var maxWidth = _self.GetMaxPageViewWidth();
            maxWidth = maxWidth > $("#" + _self.GetDocViewContainerID()).width() ? maxWidth : $("#" + _self.GetDocViewContainerID()).width();
            $("#" + _self.GetLeftDocContainerID()).css("width", maxWidth / 2);
            $("#" + _self.GetRightDocContainerID()).css("width", maxWidth / 2);
            $("#" + _self.GetRightDocContainerID()).css("left", maxWidth / 2);
            //     _RightPanelOffsetX = maxWidth / 2;
        };

        //创建命令以及工具栏按钮;
        this.CreateCmdAndCmdUI = function () {
            _pReaderApp.AddCommandUI({
                UIName: "First Page",
                CommandName: 'GoFirstPage',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnfirst' class='fwr_toolbar_btn  fwr_toobar_image_btn fwr_toobar_first_page_dis' title='" + _Language.CommandUI.GoFirstPage + "' cmd='" + "GoFirstPage" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnfirst', "fwr_toobar_first_page_nor", "fwr_toobar_first_page_dis", data.state);
                },
                Init: function () {
                    FXREADER.Common.UpdateBtnState('btnfirst', "fwr_toobar_first_page_nor", "fwr_toobar_first_page_dis", _self.GetCurPageIndex() != 0);
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "GoFirstPage",
                exec: function (data) {
                    _pReaderApp.GetMainView().GetDocView().GotoPage(0);
                }
            });


            _pReaderApp.AddCommandUI({
                UIName: "Prev Page",
                CommandName: 'GoPrevPage',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnpre' class='fwr_toolbar_btn fwr_toobar_prev_page_dis fwr_toobar_image_btn' title='" + _Language.CommandUI.GoPrevPage + "' cmd='" + "GoPrevPage" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnpre', "fwr_toobar_prev_page_nor", "fwr_toobar_prev_page_dis", data.state);
                },
                Init: function () {
                    FXREADER.Common.UpdateBtnState('btnpre', "fwr_toobar_prev_page_nor", "fwr_toobar_prev_page_dis", _self.GetCurPageIndex() != 0);
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "GoPrevPage",
                exec: function (data) {
                    _pReaderApp.GetMainView().GetDocView().GoPrevPage();
                }
            });

            _pReaderApp.AddCommandUI({
                UIName: "Next Page",
                CommandName: 'GoNextPage',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnnext' class='fwr_toolbar_btn fwr_toobar_next_page_dis fwr_toobar_image_btn' title='" + _Language.CommandUI.GoNextPage + "' cmd='" + "GoNextPage" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnnext', "fwr_toobar_next_page_nor", "fwr_toobar_next_page_dis", data.state);
                },
                Init: function () {
                    FXREADER.Common.UpdateBtnState('btnnext', "fwr_toobar_next_page_nor", "fwr_toobar_next_page_dis", _self.GetCurPageIndex() != _self.GetPageCount() - 1);
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "GoNextPage",
                exec: function (data) {
                    _pReaderApp.GetMainView().GetDocView().GoNextPage();
                }
            });

            _pReaderApp.AddCommandUI({
                UIName: "Last Page",
                CommandName: 'GoLastPage',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnlast' class='fwr_toolbar_btn fwr_toobar_last_page_dis fwr_toobar_image_btn' title='" + _Language.CommandUI.GoLastPage + "' cmd='" + "GoLastPage" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnlast', "fwr_toobar_last_page_nor", "fwr_toobar_last_page_dis", data.state);
                },
                Init: function () {
                    FXREADER.Common.UpdateBtnState('btnlast', "fwr_toobar_last_page_nor", "fwr_toobar_last_page_dis", _self.GetCurPageIndex() != _self.GetPageCount() - 1);
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "GoLastPage",
                exec: function (data) {
                    _pReaderApp.GetMainView().GetDocView().GotoPage(_pReaderApp.GetMainView().GetDocView().GetPageCount() - 1);
                }
            });

            _pReaderApp.AddCommandUI({
                UIName: "GotoPage",
                CommandName: "UpdatePage",
                State: 1,
                CreateHtmlContentFunc: function () {
                	if(FXREADER.Environment.chrome)
                		return "<div class='fwr_toolbar_page_control'><input id='textpagenum' class='fwr_text_input_chrome fwr_display_inline fwr_toolbar_page_control_pagenum' type='text' value='1' disabled='disabled'/><span id='totalPages' class='fwr_label fwr_toolbar_page_control_pagecnt' ></span></div>";
                	else
                		return "<div class='fwr_toolbar_page_control'><input id='textpagenum' class='fwr_text_input fwr_display_inline fwr_toolbar_page_control_pagenum' type='text' value='1' disabled='disabled'/><span id='totalPages' class='fwr_label fwr_toolbar_page_control_pagecnt' ></span></div>";
                },
                Init: function () {
                    var jqPageNum = $("#textpagenum");
                    jqPageNum.removeAttr("disabled");
                    $("#totalPages").html(" / " + _self.GetPageCount());

                    jqPageNum.bind("click", function () {
                        this.focus();
                        return true;
                    });
                    jqPageNum.bind("keypress", function (d) {
                        if (!$(this).hasClass("fwr_button_disabled") && d.keyCode == "13") {
                            $(this).val() > _self.GetPageCount() && $(this).val(_self.GetPageCount());
                            ($(this).val() < 1 || isNaN($(this).val())) && $(this).val(1);
                            _self.GotoPage(parseInt($(this).val() - 1));
                        }
                        return true;
                    });
                },
                OnCommandStateChange: function (data) {
                    $("#textpagenum").val(data.state);
                }
            });
            _pReaderApp.AddCommand({
                state: 1,
                name: "UpdatePage",
                exec: function (data) {
                }
            });
             _pReaderApp.AddCommandUI({
                UIName: "FitWidth",
                CommandName: 'FitWidth',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnFitWidth' class='fwr_toolbar_btn fwr_toobar_image_btn fwr_toobar_fitwidth_dis' title='" + _Language.CommandUI.FitWidth + "' cmd='" + "FitWidth" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                	if(data.state == false)
                	{
                		FXREADER.Common.UpdateBtnState("btnFitWidth", "fwr_toobar_fitwidth_dis", "fwr_toobar_fitwidth_active", true);
                	}
                	else
                	{
                		FXREADER.Common.UpdateBtnState("btnFitWidth", "fwr_toobar_fitwidth_active", "fwr_toobar_fitwidth_dis", true);
                	}
                },
                Init: function () {
                   // var scale = _self.GetScale();
                    var pCommandFitWidth = _pReaderApp.GetCommand('FitWidth');
                    if (!_self.IsFitWidth()) {
                    	pCommandFitWidth && pCommandFitWidth.SetState(false);
                    }
                    else {
                    	pCommandFitWidth && pCommandFitWidth.SetState(true);
                    }
                }
            });
          _pReaderApp.AddCommand({
                state: false,
                name: "FitWidth",
                exec: function (data) {
            		_self.FitWidth();
                }
            });

            _pReaderApp.AddCommandUI({
                UIName: "ZoomIn",
                CommandName: 'ZoomIn',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnzoomIn' class='fwr_toolbar_btn fwr_toobar_image_btn fwr_toobar_zoomin_dis'  title='" + _Language.CommandUI.ZoomIn + "' cmd='" + "ZoomIn" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnzoomIn', "fwr_toobar_zoomin_nor", "fwr_toobar_zoomin_dis", data.state);
                },
                Init: function () {
                    var scale = _self.GetScale();
                    var maxScale = scale > Config.maxZoomSize ? scale : Config.maxZoomSize;
                    var pCommandZoomIn = _pReaderApp.GetCommand('ZoomIn');
                    if (scale >= maxScale) {
                        pCommandZoomIn && pCommandZoomIn.SetState(false);
                    }
                    else {
                        pCommandZoomIn && pCommandZoomIn.SetState(true);
                    }
                    
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "ZoomIn",
                exec: function (data) {
                    var scale = _pViewLayout.GetFitWidthScale(true);
                    var curZoom = _self.GetScale();
                    var maxScale = scale > Config.maxZoomSize ? scale : Config.maxZoomSize;
                    if (curZoom >= maxScale)
                        return;
                    var tmpZoom = curZoom;
                    //var zoomIndex = -1;
                    var fitwidthNextZoomIndex = -1;
                    for (var i = 0; i < Config.zoomList.length; i++) {
                        if (curZoom == Config.zoomList[i]) {
                            if (i + 1 < Config.zoomList.length) {
                                zoomIndex = i + 1;
                                tmpZoom = Config.zoomList[i + 1];
                            }
                        }
                        else if (Config.zoomList[i] > curZoom) {
                            if (fitwidthNextZoomIndex == -1) {
                                fitwidthNextZoomIndex = i;
                            }
                        }
                    }

                    if (_self.IsFitWidth()) {
                        if (fitwidthNextZoomIndex != -1)
                            curZoom = Config.zoomList[fitwidthNextZoomIndex];
                        _self.SetFitWidth(false);
                    }
                    else {
                        if (tmpZoom < scale) {
                            curZoom = tmpZoom;
                            _self.SetFitWidth(false);
                        }
                        else if (tmpZoom > scale) {
                            if (curZoom < scale) {
                                curZoom = scale;
                                _self.SetFitWidth(true);
                            }
                            else {
                                curZoom = tmpZoom;
                                _self.SetFitWidth(false);
                            }
                        }
                        else {
                            curZoom = tmpZoom;
                            _self.SetFitWidth(true);
                        }
                    }


                    _self.OnZoom(curZoom);
                   
                }
            });
            
            _pReaderApp.AddCommandUI({
                UIName: "ZoomOut",
                CommandName: 'ZoomOut',
                State: false,
                CreateHtmlContentFunc: function () {
                    return "<a id='btnzoomOut' class='fwr_toolbar_btn fwr_toobar_image_btn fwr_toobar_zoomout_dis' ' title='" + _Language.CommandUI.ZoomOut + "' cmd='" + "ZoomOut" + "'></a>";
                },
                OnCommandStateChange: function (data) {
                    FXREADER.Common.UpdateBtnState('btnzoomOut', "fwr_toobar_zoomout_nor", "fwr_toobar_zoomout_dis", data.state);
                },
                Init: function () {
                    var scale = _self.GetScale();
                    var minScale = scale < Config.minZoomSize ? scale : Config.minZoomSize;
                    var pCommandZoomOut = _pReaderApp.GetCommand('ZoomOut');
                    if (scale <= minScale) {
                        pCommandZoomOut && pCommandZoomOut.SetState(false);
                    }
                    else {
                        pCommandZoomOut && pCommandZoomOut.SetState(true);
                    }
                }
            });
            _pReaderApp.AddCommand({
                state: false,
                name: "ZoomOut",
                exec: function (data) {
                    var scale = _pViewLayout.GetFitWidthScale(true);
                    var curZoom = _self.GetScale();
                    var minScale = scale < Config.minZoomSize ? scale : Config.minZoomSize;
                    if (curZoom <= minScale)
                        return;
                    var tmpZoom = curZoom;
                    //var zoomIndex = -1;
                    var fitwidthNextZoomIndex = -1;
                    for (var i = Config.zoomList.length - 1; i >= 0; i--) {
                        if (curZoom == Config.zoomList[i]) {
                            if (i - 1 >= 0) {
                                zoomIndex = i - 1;
                                tmpZoom = Config.zoomList[i - 1];
                            }
                        }
                        else if (Config.zoomList[i] < curZoom) {
                            if (fitwidthNextZoomIndex == -1) {
                                fitwidthNextZoomIndex = i;
                            }
                        }
                    }
                    if (_self.IsFitWidth()) {
                        if (fitwidthNextZoomIndex != -1)
                            curZoom = Config.zoomList[fitwidthNextZoomIndex];
                        _self.SetFitWidth(false);
                    }
                    else {
                        if (tmpZoom > scale) {
                            curZoom = tmpZoom;
                            _self.SetFitWidth(false);
                        }
                        else if (tmpZoom < scale) {
                            if (curZoom > scale) {
                                curZoom = scale;
                                _self.SetFitWidth(true);
                            }
                            else {
                                curZoom = tmpZoom;
                                _self.SetFitWidth(false);
                            }
                        }
                        else {
                            curZoom = tmpZoom;
                            _self.SetFitWidth(true);
                        }
                    }

                    _self.OnZoom(curZoom);
                   
                }
            });
            function _getCurrentZoomList()
            {
             	var fitWidthScale = _pViewLayout.GetFitWidthScale(true);
            	var zoomList = [];
            	var bFitWidthAppended = false;
            	for (var i = 0; i < Config.zoomList.length; i++) {
                    if(Config.zoomList[i] <= fitWidthScale)
                    	zoomList.push(Config.zoomList[i]);
                    else
                    {
                    	if(!bFitWidthAppended)
                    	{
                    		zoomList.push(_Language.CommandUI.FitWidth);
                    		bFitWidthAppended = true;
                    	}
                    	zoomList.push(Config.zoomList[i]);
                    }
                }
            	if(!bFitWidthAppended)
            	{
            		zoomList.push(fitWidthScale);
            	}
            	return zoomList;
            }
            _pReaderApp.AddCommandUI({
                UIName: "ZoomSlider",
                CommandName: 'OnZoom',
                State: false,
                CreateHtmlContentFunc: function () {
                    var html = "<div id='zoom_select_slider' class='fwr_toobar_image_btn' style='width:80px;margin-top:9px;'></div>";
                    return html;
                },
                OnCommandStateChange: function (data) {
                	var curZoom = _self.GetScale();
                	var currentValue = -1;
                	var zoomList = _getCurrentZoomList();
                	for (var i = 0; i < zoomList.length; i++) {
                		if(zoomList[i] == curZoom || (zoomList[i]==_Language.CommandUI.FitWidth && _self.IsFitWidth()))
                		{
                			currentValue = i+1;
                			break;
                		}
                	}
                	$("#zoom_select_slider" ).slider('value',currentValue);   
                },
                Init: function () {
                	var currentValue = -1;
                	var curZoom = _self.GetScale();
                	var zoomList = _getCurrentZoomList();
                	for (var i = 0; i < zoomList.length; i++) {
                		if(zoomList[i]==curZoom || (zoomList[i]==_Language.CommandUI.FitWidth && _self.IsFitWidth()))
                		{
                			currentValue = i+1;
                			break;
                		}
                	}
                	$("#zoom_select_slider" ).slider({
                	      range: "max",
                	      min: 1,
                	      max: Config.zoomList.length+1,
                	      value: currentValue,
                	      slide: function( event, ui ) {
                	    	  var zoomList = _getCurrentZoomList();
                	    	  var zoomSelected = zoomList[ui.value-1];
                	    	  if(zoomSelected == _Language.CommandUI.FitWidth)
	                       	  {
	                       		   if(!_self.IsFitWidth())
	                       		   {
	                       			   _self.SetFitWidth(true);
	                              		   var fitScale = _pViewLayout.GetFitWidthScale(true);
	                           		   _self.OnZoom(fitScale);
	                       		   }
	            
	                       	   }
	                       	   else
	                       	   {
	                       		   _self.SetFitWidth(false);
	                                  var curZoom = zoomSelected;
	                                  _self.OnZoom(curZoom);
	                       	   }
	                	     }
                	});
                }
            });


            _pReaderApp.AddCommandUI({
                UIName: "SelectZoom",
                CommandName: 'OnZoom',
                State: false,
                CreateHtmlContentFunc: function () {
                    var html = "<span class='fwr-select-wrapper'><select id='zoomSel' class='fwr_text_input fwr_toolbar_zoomsel_select fwr-custom-select'  disabled='disabled'>";
                    for (var i = 0; i < Config.zoomList.length; i++) {
                        html += "<option value='" + Config.zoomList[i] * 100 + "'>" + Config.zoomList[i] * 100 + "%</option>";
                    }
                    html += "<option value='" + _Language.CommandUI.FitWidth + "'>" + _Language.CommandUI.FitWidth + "</option></select>";
                    html += "</span>";
                    return html;
                },
                OnCommandStateChange: function (data) {
                    var jqZoomSel = $("#zoomSel");
                    if(_self.IsFitWidth())
                    {
                    	jqZoomSel.attr("value", _Language.CommandUI.FitWidth);
                    	var jq =jqZoomSel.parent().children(".holder");
                    	jq.text(selectedOption);
                    	jq.text(_Language.CommandUI.FitWidth);
                    }
                    else
                    {
                    	jqZoomSel.attr("value", data.state * 100);
                    	var selectedOption = jqZoomSel.find(":selected").text();
                    	var jq =jqZoomSel.parent().children(".holder");
                    	jq.text(selectedOption);
                    }
                },
                Init: function () {
                    var jqZoomSel = $("#zoomSel");
                    jqZoomSel.removeAttr("disabled");
                    var scale = _self.GetScale();
                    if(_self.IsFitWidth())
                    {
                    	jqZoomSel.attr("value", _Language.CommandUI.FitWidth);
                    }
                    else
                    {
                    	jqZoomSel.attr("value", scale * 100);
                    }
                   jqZoomSel.bind("change", function () {
                	   if(jqZoomSel.val() == _Language.CommandUI.FitWidth)
                	   {
                		   if(!_self.IsFitWidth())
                		   {
                			   _self.SetFitWidth(true);
                       		   var fitScale = _pViewLayout.GetFitWidthScale(true);
                    		   _self.OnZoom(fitScale);
                		   }
     
                	   }
                	   else
                	   {
                		   _self.SetFitWidth(false);
                           var curZoom = jqZoomSel.val() / 100;
                           _self.OnZoom(curZoom);
                	   }
   
                    });
                }
            });

            _pReaderApp.AddCommand({
                state: _self.GetScale(),
                name: "OnZoom",
                exec: function (data) {
                	alert(000);
                }
            });


            //添加下载按钮;
            if(Config.showDownloadLimitBtn || _pReaderApp.CanDownloadPDF())
            {
            	_pReaderApp.AddCommandUI({
                    UIName: "DownLoadPDF",
                    CommandName: null,
                    CreateHtmlContentFunc: function () {
                        return "<a id='btnDownload'  class='fwr_toobar_download_dis fwr_toolbar_text_btn' title='" + _Language.CommandUI.DownloadPDFTitle + "'>"+
                        "<span class='fwr_img_24by24 fwr_toolbar_img'><img alt='' class='fwr_img_24by24' src='images/downloadfile_nor.png'></span><span class='fwr_toollabel'>" + _Language.CommandUI.DownloadPDF + "</span></a>";
                    },
                    Init: function () {
                        if (_pReaderApp.CanDownloadPDF()) {
                            FXREADER.Common.UpdateBtnState('btnDownload', "fwr_toobar_download_nor", "fwr_toobar_download_dis", true);
                            $("#btnDownload").bind('click', function () {
                                if ($("#btnDownload").hasClass("fwr_toobar_download_nor"))
                                    window.open(Config.Url.GetSourcePDF+"?fileid=" + _pReaderApp.GetFileID());
                                return false;
                            });
                        }
                    }
                });
           	}
        };


        this.BindScrollEvent = function () {
            $('#' + _DocViewContainerID).scroll(_self.OnPageScroll);
        };

        this.UnBindScrollEvent = function () {
            $('#' + _DocViewContainerID).unbind("scroll");
        };

        this.GetViewMode = function () {
            return _stLayoutInfo.nShowMode;
        };

        //获取已经创建的页面列表
        this.GetCreatedPageNums = function () {
            var k = 0;
            var pagenums = [];
            var iPageCnt = _self.GetPageCount();
            for (var i = 0; i < iPageCnt; i++) {
                if (_self.GetPageView(i).IsContentCreated()) {
                    pagenums[k] = i;
                    k++;
                }

            }
            return pagenums;
        };


        //根据页面索引，创建包含该页面的页面区间;
        this.CreatePages = function (nPageIndex) {
            var iPageCnt = _self.GetPageCount();
            if (nPageIndex < 0 || nPageIndex >= iPageCnt)
                return false;
            if (_CheckPageCreated(nPageIndex))  //已经创建;
                return true;
            var pageInterval2Create = _GetPageInterval2Create(nPageIndex);
            if (pageInterval2Create.m_nStartIndex < 0)
                pageInterval2Create.m_nStartIndex = 0;
            if (pageInterval2Create.m_nEndIndex >= iPageCnt)
                pageInterval2Create.m_nEndIndex = iPageCnt - 1;
            var nInsertAfterPageIndex = _GetInsertAfterIndex(pageInterval2Create.m_nStartIndex);
            _CreatedPageArray.push(pageInterval2Create);
            return _pViewLayout.CreatePagesView(pageInterval2Create.m_nStartIndex, pageInterval2Create.m_nEndIndex, nInsertAfterPageIndex);
        };



        //初始化滚动条;
        this.InitializeScrollbar = function (settings) {
            if (_ScrollApi != null)
                return _ScrollApi;
            var jqDocViewContainer = $("#" + _DocViewContainerID);
            var api_element = jqDocViewContainer.jScrollPane(settings);
            _ScrollApi = api_element.data('jsp');
            return _ScrollApi;
        };
        //重新初始化滚动条;
        this.ReInitializeScrollBar = function (settings) {
            if (_ScrollApi == null)
                throw new Error('Scroll Api is null!');
            _pReaderApp.OnPreDocViewResize();
            if (settings != null)
                _ScrollApi.reinitialise(settings);
            else
                _ScrollApi.reinitialise();
            _pReaderApp.OnDocViewResize();
        };
        
        this.GetFitWidthScale = function()
		{
			 return _pViewLayout.GetFitWidthScale(true);
		};


        this.GetScrollApi = function () {
            return _ScrollApi;
        };
        /**
         * @description Scrolls view.
 		* @param {Number} offsetX   offset in x-axis.
 		* @param {Number} offsetY   offset in y-axis.
         */
        this.MovePage = function (offsetx, offsety) {
            if (_ScrollApi != null)
                _ScrollApi.scrollBy(offsetx, offsety);
        };

        this.OnPageScroll = function () {
            var oldVisableRange = _pViewLayout.GetVisablePageRange();
            var range = _pViewLayout.GetVisablePageRange();
            var nLastVisablePageIndex = range.end;
            var nFirstVisablePageIndex = range.begin;
            if (_ScrollApi != null) {
                //   var nCurPosY = _ScrollApi.getContentPositionY();
                //  var nContentHeight = _ScrollApi.getContentHeight();
                //   var percentScrolledY = _ScrollApi.getPercentScrolledY();
                var offsetX = _ScrollApi.getContentPositionX();
                var bUpdate = false;
                var offsetY = _pViewLayout.GetPageOffsetDocY(_iCurPageIndex);
                if (nFirstVisablePageIndex >= 1 && !_self.GetPageView(nFirstVisablePageIndex - 1).IsContentCreated()) {
                    bUpdate = _self.CreatePages(nFirstVisablePageIndex - 1);
                }
                if (nLastVisablePageIndex < _self.GetPageCount() - 1 && !_self.GetPageView(nLastVisablePageIndex + 1).IsContentCreated()) {
                    bUpdate |= _self.CreatePages(nLastVisablePageIndex + 1);
                }
                if (bUpdate) {
                    _ScrollApi.scrollToX(offsetX);
                }
                _pViewLayout.ProgressiveUpdateState(_iCurPageIndex, nFirstVisablePageIndex, nLastVisablePageIndex, offsetY, true, true);
            }
            range = _pViewLayout.CountDisplayPageRange();
            var oldPageIndex = _iCurPageIndex;
            _iCurPageIndex = range.current;
            _UpdatePageIndex(oldPageIndex);

            // Resets timeout to prevent page load per scroll event
            if (_documentScrollTimeout) {
                clearTimeout(_documentScrollTimeout);
            }
            _documentScrollTimeout = setTimeout(function () {
                _self.LoadPages(range);
                var newVisableRange = _pViewLayout.GetVisablePageRange();
                var jqPagesContainerDiv = $("#" + _self.GetDocViewContainerID());
                var contentPaneHeight = jqPagesContainerDiv.height(); // $('#mainContainer').height();
                var contentPanelWidth = jqPagesContainerDiv.width();
                var contentPanelOffset = jqPagesContainerDiv.offset();
                for (var i = oldVisableRange.begin; i <= oldVisableRange.end; i++) {
                    if (i < newVisableRange.begin || i > newVisableRange.end) {
                        _pReaderApp.OnPageInvisible(_self.GetPageView(i));
                    }
                }
                for (var i = newVisableRange.begin; i <= newVisableRange.end; i++) {
                    _pReaderApp.OnPageVisible(_self.GetPageView(i), contentPanelWidth, contentPaneHeight, contentPanelOffset); //测试
                }
            }, 100);


            
            _pReaderApp.OnDocViewScroll();
        };

        //加载页面;
        this.LoadPages = function (range) {
            var jqPagesContainerDiv = $("#" + _self.GetDocViewContainerID());
            var contentPaneHeight = jqPagesContainerDiv.height(); // $('#mainContainer').height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();
            var scrollWidth = 22;
            if(FXREADER.Environment.mobile || FXREADER.Environment.iOS)
            	scrollWidth = 1;
            for (var i = range.begin - 1; i <= range.end + 1; i++) {
                var pPageView = _self.GetPageView(i);
                if (pPageView) {
                    if (i > range.begin - 1 && i <= range.end && !pPageView.IsPageLoaded()) {
                        var page_width = pPageView.GetPageViewWidth(),
						page_height = pPageView.GetPageViewHeight();
                        var jqPageContainer = $("#" + pPageView.GetPageContainerID());
                        var visableWidth = contentPanelWidth;
                        var visableHeight = contentPaneHeight;
                        if (_ScrollApi != null) {
                            if (_ScrollApi.getIsScrollableH())
                                visableHeight -= scrollWidth;
                            //减去滚动条宽度;
                            if (_ScrollApi.getIsScrollableV())
                                visableWidth -= scrollWidth;

                        }
                        var page_pos = jqPageContainer.offset();

                        var bottomCuted = page_pos.top + page_height - (contentPanelOffset.top + visableHeight);
                        if (bottomCuted < 0)
                            bottomCuted = 0;
                        var topCutted = 0;
                        if ((page_pos.top < contentPanelOffset.top)) {
                            topCutted = contentPanelOffset.top - page_pos.top;
                        }
                        var leftCutted = contentPanelOffset.left - page_pos.left;
                        if (leftCutted < 0)
                            leftCutted = 0;
                        var rightCutted = page_pos.left + page_width - (contentPanelOffset.left + visableWidth);
                        if (rightCutted < 0)
                            rightCutted = 0;
                        var jqLoadDiv = $("#" + pPageView.GetPageLoaderImgID());
                        if (jqLoadDiv != null) {
                            if (page_height - bottomCuted - topCutted < 24) // page visable height less than the size of loading icon
                            {
                                bottomCuted = 0;
                                topCutted = 0;
                            }
                            jqLoadDiv.css({ marginLeft: -12 - (rightCutted-leftCutted) / 2, marginTop: -12 - (bottomCuted - topCutted) / 2 });
                        }
                    }
                    _pPageViewRender.RenderPage(pPageView, FXREADER.Config.requestRetryCount);
                }
            }
        };

        //调整DocView视口区域
        this.OnSize = function (width, height, offsetLeft, offsetTop) {
        	
            _self.UnBindScrollEvent();
            //重置页面状态，这样会重新计算页面宽高和左边偏移量;-
            _self.ResetScaleUpdateState();
            _DocViewWidth = width;
            _DocViewHeight = height;
            $("#" + _DocViewContainerID).css({ width: _DocViewWidth, height: _DocViewHeight, left: offsetLeft, top: offsetTop });
            _self.SetDocViewOffsetLeft(offsetLeft);
            _self.SetDocViewOffsetTop(offsetTop);
            var nOldPage = _iCurPageIndex;
            if (_ScrollApi)
                _ScrollApi.getContentPane().css({ left: 0 }); //防止滚动条处于负值状态，放大是页面位置错误问题;
            _pViewLayout.ReInitializeScrollBar();
            if(_self.IsFitWidth())
        	{
        		var newScale = _pViewLayout.GetFitWidthScale(true);
        		_self.OnZoom(newScale);
        	}
            _self.OnPageScroll();
            _self.BindScrollEvent();
            //保持原来的页数;
            _ScrollApi.scrollToElement("#" + _self.GetPageView(nOldPage).GetPageContainerID(), true, false);
            
        };

        this.UpdateZoomCmdState = function (scale) {
        	var pCommandFitWidth = _pReaderApp.GetCommand('FitWidth');
           	if(!_self.IsFitWidth())
        	{ 		
           		pCommandFitWidth && pCommandFitWidth.SetState(false);
        	}
           	else
           	{
           		pCommandFitWidth && pCommandFitWidth.SetState(true);
           	}
            var pCommandZoomIn = _pReaderApp.GetCommand('ZoomIn');
            var pCommandZoomOut = _pReaderApp.GetCommand('ZoomOut');
            var pCommandOnZoom = _pReaderApp.GetCommand('OnZoom');
            if (scale >= Config.maxZoomSize) {
                pCommandZoomIn && pCommandZoomIn.SetState(false);
            }
            else {
                pCommandZoomIn && pCommandZoomIn.SetState(true);
            }

            if (scale <= Config.minZoomSize) {
                pCommandZoomOut && pCommandZoomOut.SetState(false);
            }
            else {
                pCommandZoomOut && pCommandZoomOut.SetState(true);
            }
            pCommandOnZoom && pCommandOnZoom.SetState(scale);
        };

        this.OnZoom = function (scale) {
            if (scale == _pViewLayout.GetScale()) {
                _self.UpdateZoomCmdState(scale);
                return;
            }
            _self.UnBindScrollEvent();
            _pViewLayout.SetScale(scale);
            //重置页面状态，这样会重新计算页面宽高和左边偏移量;
            _self.ResetScaleUpdateState();
            _self.ResetPageLoadState();
            var nOldPage = _iCurPageIndex;
            if (_ScrollApi)
                _ScrollApi.getContentPane().css({ left: 0 }); //防止滚动条处于负值状态，放大是页面位置错误问题;
            //_pViewLayout.ReInitializeScrollBar();
            _self.OnPageScroll();
            //保持原来的页数;
            _ScrollApi.scrollToElement("#" + _self.GetPageView(nOldPage).GetPageContainerID(), true, false);
            _iCurPageIndex = nOldPage;
            _self.BindScrollEvent();
            //_pViewLayout.ReInitializeScrollBar();
            _self.UpdateZoomCmdState(scale);
            _UpdatePageIndex(nOldPage);
            _pReaderApp.OnDocViewZoom(scale);
        };

        this.GetScale = function () {
            return _pViewLayout.GetScale();
        };

        this.SetScale = function (scale) {
            _pViewLayout.SetScale(scale);
        };

        this.ResetScaleUpdateState = function () {
            var iPageCnt = _self.GetPageCount();
            for (var i = 0; i < iPageCnt; i++) {
                var pPageView = _self.GetPageView(i);
                if (pPageView.IsContentCreated())
                    pPageView.SetScaleUpdated(false);
            }
        };

        this.ResetPageLoadState = function () {
            var iPageCnt = _self.GetPageCount();
            for (var i = 0; i < iPageCnt; i++) {
                var pPageView = _self.GetPageView(i);
                if (pPageView.IsContentCreated())
                    pPageView.SetPageLoaded(false);
            }
        };

        this.GetVisablePageRange = function()
        {
        	return _pViewLayout.GetVisablePageRange();
        };
        
        /**
         * @description Jump to a page.
         * @param {Number} iPageIndex page index.
         * @param {Number} OffsetX offset in x-axis.
         * @param {Number} OffsetY offset in y-axis.
         */
        this.GotoPage = function (iPageIndex, OffsetX, OffsetY) {
            if (_ScrollApi == null)
                return false;
            var oldVisableRange = _pViewLayout.GetVisablePageRange();
            //先取消监控滚动事件;
            _self.UnBindScrollEvent();
            OffsetY = OffsetY ? OffsetY : 0;
            _nDestPageOffsetY = OffsetY;
            if (OffsetX == null)
                OffsetX = _ScrollApi.getContentPositionX();
            if (iPageIndex < 0 || iPageIndex >= _self.GetPageCount())
                return false;
            var bUpdate = false;
            var nMaxNewPagesPerTime = Config.maxNewPagesPerTime;
            if (nMaxNewPagesPerTime == -1)
                nMaxNewPagesPerTime = _self.GetPageCount();
            if ((iPageIndex + 1) % nMaxNewPagesPerTime == 0) {
                bUpdate = this.CreatePages(iPageIndex + 1);
                bUpdate |= this.CreatePages(iPageIndex);
            }
            else {
                var nPage2Create = iPageIndex + 1;
                if (nPage2Create >= _self.GetPageCount())
                    nPage2Create = _self.GetPageCount() - 1;
                if (this.CreatePages(nPage2Create) == true) {
                    bUpdate = true;
                }
            }
            var oldPageIndex = _iCurPageIndex;
            _iCurPageIndex = iPageIndex;
            _ScrollApi.scrollToElement("#" + _self.GetPageView(iPageIndex).GetPageContainerID(), true, false, OffsetY);
            _ScrollApi.scrollToX(OffsetX);
            if (_pViewLayout.ProgressiveUpdateState(iPageIndex, _iCurPageIndex, _iCurPageIndex, OffsetY, true, true)) {
                _pViewLayout.CountDisplayPageRange();
            }

            _self.CreateNearPage(iPageIndex, OffsetY);
            var newVisableRange = _pViewLayout.GetVisablePageRange();
            
            _iCurPageIndex = newVisableRange.current;
            _UpdatePageIndex(oldPageIndex);
            _self.LoadPages(newVisableRange);

            var jqPagesContainerDiv = $("#" + _self.GetDocViewContainerID());
            var contentPaneHeight = jqPagesContainerDiv.height(); // $('#mainContainer').height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();
            for (var i = oldVisableRange.begin; i <= oldVisableRange.end; i++) {
                if (i < newVisableRange.begin || i > newVisableRange.end) {
                    _pReaderApp.OnPageInvisible(_self.GetPageView(i));
                }
            }
            for (var i = newVisableRange.begin; i <= newVisableRange.end; i++) {
                _pReaderApp.OnPageVisible(_self.GetPageView(i), contentPanelWidth, contentPaneHeight, contentPanelOffset); //测试
            }

            this.BindScrollEvent(); //恢复监控滚动事件

            return true;
        };

        /**
         * @description Goto next page.
         */
        this.GoNextPage = function () {
            _pViewLayout.GoNextPage();
        };
        /**
         * @description Goto previous page.
         */
        this.GoPrevPage = function () {
            _pViewLayout.GoPrevPage();
        };
        /**
         * @description Get an array of the page indexes which are visable.
 		* @retrun {Array} an array of the page indexes which are visable.
         */
        this.GotoPageByDest = function (destinfo) {
            _pViewLayout.GotoPageByDest(destinfo);
        };

        this.GetDisplayPageRange = function () {
            return _pViewLayout.GetDisplayPageRange();
        };

        this.GetReaderApp = function () {
            return _pReaderApp;
        };

        /**
         * @description Get the App object.
 		* @retrun {FXREADER.CReaderApp} the App object.
         */
        this.CreateNearPage = function (iDestPageIndex, offsetY) {
            var range = _pViewLayout.CountDisplayPageRange();
            var nLastVisablePageIndex = range.end;
            var nFirstVisablePageIndex = range.begin;
            if (_ScrollApi != null) {
                var bUpdate = false;
                //var nOldIndex = _iCurPageIndex;

                if (nFirstVisablePageIndex >= 1 && !_self.GetPageView(nFirstVisablePageIndex - 1).IsContentCreated()) {
                    bUpdate = _self.CreatePages(nFirstVisablePageIndex - 1);
                }
                if (nLastVisablePageIndex < _self.GetPageCount() - 1 && !_self.GetPageView(nLastVisablePageIndex + 1).IsContentCreated()) {
                    bUpdate |= _self.CreatePages(nLastVisablePageIndex + 1);
                }

                if (bUpdate) {
                    var offsetX = _ScrollApi.getContentPositionX();
                    range = _pViewLayout.CountDisplayPageRange();
                    nLastVisablePageIndex = range.end;
                    nFirstVisablePageIndex = range.begin;
                    _pViewLayout.ProgressiveUpdateState(iDestPageIndex, nFirstVisablePageIndex, nLastVisablePageIndex, offsetY, true, false);
                    //继续创建直到超出当前可视区域;
                    _pViewLayout.ReInitializeScrollBar();
                    _ScrollApi.scrollToElement("#" + _self.GetPageView(iDestPageIndex).GetPageContainerID(), true, false, offsetY);
                    _ScrollApi.scrollToX(offsetX);
                    _self.CreateNearPage(iDestPageIndex, offsetY);
                    _pViewLayout.ReInitializeScrollBar();
                    _ScrollApi.scrollToElement("#" + _self.GetPageView(iDestPageIndex).GetPageContainerID(), true, false, offsetY);
                    _ScrollApi.scrollToX(offsetX);
                }
            }
        };
        
        this.ClearAllSelection = function()
        {
        	
        };
        
        this.SetChangeMark = function()
        {
        	
        };
    };

    return FXREADER.PDFView.CPDF_DocView;

});